Skip to content

fix: complete io_destroy#1165

Merged
ZR233 merged 2 commits into
rcore-os:devfrom
Alayfolk64:fix/aio
Jun 6, 2026
Merged

fix: complete io_destroy#1165
ZR233 merged 2 commits into
rcore-os:devfrom
Alayfolk64:fix/aio

Conversation

@Alayfolk64

@Alayfolk64 Alayfolk64 commented Jun 6, 2026

Copy link
Copy Markdown
Contributor

修复说明

本 PR 是对 追踪issue的补充,已修复其中所述的三个问题。

问题 1:AIO context 缺少进程退出清理

已修复。

本次改动把 io_destroy 中的核心销毁流程抽成内部复用逻辑,并新增按进程
pid 清理 AIO context 的接口。进程最后一个线程退出时,会在释放/清理
address space slot 之前调用该接口,清理该进程拥有的全部 AIO context。

清理行为复用显式 io_destroy 的语义:从全局 AIO_CONTEXTS 表移除 context,
设置 destroying,取消队列中尚未执行的请求,唤醒并等待 worker/inflight
请求结束,最后 unmap AIO ring。这样即使用户进程没有显式调用 io_destroy
退出路径也不会遗留全局 AIO context、worker,或继续持有已退出进程的 address
space 引用。

同时补充了一个负向/回归测试:子进程 io_setup 后提交一个阻塞型
IOCB_CMD_POLL 请求,然后不调用 io_destroy 直接退出;父进程等待子进程正常
退出,用来覆盖“进程退出触发 AIO 隐式清理”这条路径。

问题 2:IOCB_FLAG_RESFD 未校验 aio_resfd 必须是 eventfd

已修复。

resolve_resfd 不再只通过 get_file_like(cb.resfd) 接受任意 FileLike
而是显式 downcast 为 EventFd。如果 IOCB_FLAG_RESFD 指向的 fd 不是
eventfd,io_submit 阶段直接返回 EINVAL,不会把普通文件、pipe 或其他 fd
当成 AIO completion 通知目标。

AioRequest 中保存的 completion 通知目标也从通用 FileLike 收窄为
EventFd,完成路径只会对合法 eventfd 写入 8 字节计数通知。这样可以避免普通
可写文件被误写入 8 字节,也避免不可写 fd 的通知错误被 completion 路径吞掉。

测试中补充了 IOCB_FLAG_RESFD + 普通文件 fd 的负向用例,确认该组合在
io_submit 阶段失败并返回 EINVAL

问题 3:MySQL app prebuild.sh 依赖 passwordless sudo

这个问题属于 MySQL app rootfs 准备流程的权限约束,不是 AIO 逻辑问题。
当前 apps/starry/mysql/prebuild.sh 需要把 ext4 rootfs 镜像接到 loop device
并 mount 到临时目录,然后向镜像内安装 MySQL、解包 Debian 依赖并写入
/root/mysql-env.shlosetupmount 都需要 root 权限,所以普通宿主机
用户没有 root 或 passwordless sudo 时,cargo xtask starry app qemu -t mysql --arch x86_64 会在 QEMU 启动前失败。

本次已在 apps/starry/mysql/README.mdapps/starry/mysql/README_CN.md
靠前位置补充说明:MySQL rootfs 准备必须以 root 运行,或者由具备
passwordless sudo 的用户运行;也可以在具备 root 权限的容器中执行,因为
root 容器可以直接完成 loop mount 流程。

需要注意的是,tmp/axbuild/rootfs/rootfs-x86_64-mysql.imgtarget/mysql
可以复用已生成的 rootfs 与下载缓存,但当前 prebuild.sh 仍会检查、扩容、挂载
并刷新镜像内容,因此即使缓存存在,现有流程也仍然需要 root 权限。

@mai-team-app mai-team-app Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PR 审核总结

修改内容

本 PR 完善了 io_destroy 系统调用和 AIO 子系统的实现,包含两个逻辑部分:

  1. AIO 子系统修复aio.rs + task/ops.rs

    • AioRequest.resfd 类型从 Option<Arc<dyn FileLike>> 改为 Option<Arc<EventFd>>,并通过 downcast_arc 验证 IOCB_FLAG_RESFD 必须指向 eventfd(符合 Linux 语义)
    • 提取 destroy_context() 辅助函数,供 sys_io_destroycleanup_aio_contexts_for_pid 共用
    • 新增 cleanup_aio_contexts_for_pid(),在进程最后一个线程退出时自动清理所有 AIO 上下文,防止内核资源泄漏
    • 修复 sys_io_destroy 中对全局上下文表的 remove 操作,正确捕获返回的 Arc
  2. 测试覆盖

    • test-io-destroy:新增子进程退出时不调用 io_destroy 的隐式清理回归测试
    • test-io-submit:新增 IOCB_FLAG_RESFD 搭配非 eventfd fd 时返回 EINVAL 的验证
  3. MySQL 文档README.md + README_CN.md

    • 补充宿主机 root/sudo 权限要求说明

实现逻辑分析

  • resfd 验证:Linux 内核要求 IOCB_FLAG_RESFD 仅接受 eventfd(eventfd_fops)。base 分支的旧实现接受任意 FileLike,不符合 Linux 行为。PR 使用 downcast_arc::<EventFd>() 做类型检查,正确匹配内核语义。
  • 进程退出清理:Linux 在 exit_files() 中调用 io_destroy() 清理所有 AIO 上下文。PR 将 cleanup_aio_contexts_for_pid() 放在 do_exit()exit_thread() 返回 true(最后一个线程)之后、close_all_fds() 之前,与 Linux 的清理顺序一致。这样 worker 任务在销毁过程中仍可引用已打开的 fd。
  • destroy_context 提取:将上下文销毁逻辑(设置 destroying 标志、清空队列、等待 inflight 排空、unmap ring buffer)提取为独立函数,避免重复代码。
  • sys_io_destroy 修复:旧代码 AIO_CONTEXTS.write().remove(&context.id) 忽略了 remove 返回值。新代码正确捕获移除的 Arc 并传入 destroy_context()

验证结果

  • cargo fmt --check:通过
  • cargo xtask clippy --package starry-kernel:13 个 feature 组合全部通过(0 warnings)
  • CI 状态:全部通过(SUCCESS)。成功的非跳过检查包括:Check formattingRun sync-lintRun clippyTest with std、所有架构的 QEMU 测试(starry/aarch64/riscv64/x86_64/loongarch64、arceos、axvisor)和自托管板卡测试。跳过的检查为 run_container 互斥对应的 run_host 任务,属于预期行为。
  • 无 crates.io patch 依赖

重复/重叠分析

  • 搜索 io_destroyaioEventFdresfd 关键词的 open PR:仅本 PR(#1165)命中
  • PR #1160(Wayland app)和 PR #1076(self-compile)在搜索中出现但实际不重叠:前者是 Wayland app 支持,后者是自编译功能
  • base 分支当前无 AIO 进程退出清理实现,本 PR 是唯一的补充

回归测试评估

  • child_exit_without_io_destroy():fork 子进程 → io_setup → pipe → io_submit(POLL) → 子进程 _exit(0)。验证隐式 AIO 清理后子进程正常退出(exit status 0)。这是对进程退出清理路径的有效回归测试。
  • test-io-submit 新增用例:IOCB_FLAG_RESFD 搭配普通文件 fd(非 eventfd)→ 验证 io_submit 返回 EINVAL。覆盖 resfd 类型验证逻辑。

无阻塞问题

所有检查通过,实现符合 Linux 语义,测试覆盖了关键路径,CI 全绿。没有发现阻塞性问题。

Powered by mimo-v2.5-pro

@ZR233 ZR233 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

审查总结

本 PR 修复了 追踪 issue #1157 中描述的三个问题,实现逻辑正确,测试覆盖充分,所有验证通过。

问题 1:AIO context 进程退出清理

实现逻辑:

  • sys_io_destroy 中的核心销毁流程抽取为 destroy_context() 内部函数,逻辑复用干净
  • 新增 cleanup_aio_contexts_for_pid(pid):获取写锁 → 按 owner 过滤并从全局表移除 → 释放锁 → 逐个调用 destroy_context()
  • do_exit()exit_thread() 返回 true(最后一个线程)时,在 close_all_fds() 和释放 address space 之前调用清理

正确性分析:

  • 清理顺序正确:AIO context 持有进程 address space 的 Arc 引用,必须在释放 address space slot 之前销毁
  • 锁设计合理:先在写锁内完成全局表移除,再释放锁后执行 wait_for_inflight_drain 等阻塞操作,避免死锁
  • sys_io_destroy 无竞争:若另一线程已通过 sys_io_destroy 移除同一 context,cleanup_aio_contexts_for_pid 的过滤不会匹配到它;反之亦然
  • sys_io_destroy 改进:从 lookup_context + remove 改为 remove(&context.id).ok_or_else(invalid_context),修复了旧代码在 remove 返回 None 时仍执行 destroy 的潜在双重销毁问题

问题 2:IOCB_FLAG_RESFD 校验

实现逻辑:

  • resolve_resfd()get_file_like + 接受任意 FileLike 改为 get_file_like + downcast_arc::<EventFd>()
  • AioRequest.resfd 类型从 Option<Arc<dyn FileLike>> 收窄为 Option<Arc<EventFd>>
  • notify_resfd() 参数从 &Arc<dyn FileLike> 收窄为 &EventFd
  • 非 eventfd fd 返回 EINVAL,符合 Linux 行为

正确性分析:

  • 类型系统层面保证 completion 路径只对合法 EventFd 写入 8 字节计数
  • 避免普通可写文件被误写入 8 字节数据
  • 避免不可写 fd 的通知错误被 completion 路径吞掉

问题 3:MySQL README 文档

文档变更正确描述了 rootfs 准备对 root/passwordless sudo 的权限要求,说明了循环缓存机制。纯文档改动,无行为变更。

测试覆盖

  • test-io-destroy 新增 child_exit_without_io_destroy():子进程 io_setup → 提交阻塞 IOCB_CMD_POLL → 不调用 io_destroy 直接 _exit(0);父进程 waitpid 验证子进程正常退出。内核日志确认清理路径:cleared queue, inflight=1, pending=1all inflight drained
  • test-io-submit 新增负向用例:IOCB_FLAG_RESFD + 普通文件 fd → 验证 io_submit 返回 EINVAL

两个测试都是针对具体 bug 的回归测试,覆盖了修复路径。

验证结果

检查项 结果
cargo fmt --check ✅ 通过
cargo xtask clippy --package starry-kernel(13 个 feature 检查) ✅ 全部通过
cargo xtask starry test qemu --arch x86_64 -c syscall ✅ 全部通过(test-io-destroy + test-io-submit 含新增用例)
CI (GitHub Actions) ✅ Starry 四架构全部通过,fmt/clippy/sync-lint 通过

重复/重叠分析

搜索了 open PR 和 issues,除本 PR 外无其他修复 AIO 清理或 resfd 校验的 PR,无重复。

结论

实现正确、测试充分、无阻塞问题,批准合并。

@ZR233
ZR233 merged commit 108707e into rcore-os:dev Jun 6, 2026
49 checks passed
This was referenced Jun 6, 2026
aptacc2421 pushed a commit to aptacc2421/tgoskits that referenced this pull request Jun 14, 2026
* fix: complete io_destroy

* chore: revise README.md
luodeb pushed a commit that referenced this pull request Jun 30, 2026
* fix: complete io_destroy

* chore: revise README.md
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants